
#include <stdio.h>      /* printf */
#include <string.h>     /* strcat */
#include <stdlib.h>     /* strtol */
#include <string>

// Вычисление следующего большего числа с тем же количеством еденичных битов
// not applied for x = 0
unsigned int snoob(unsigned int x)
{
  unsigned int smallest, ripple, ones;

                                     // x = xxx0 1111 0000
  smallest = x & -x;                 //     0000 0001 0000
  ripple   = x + smallest;           //     xxx1 0000 0000
  ones     = x ^ ripple;             //     0001 1111 0000
  ones     = (ones >> 2) / smallest; //     0000 0000 0111
  return ripple | ones;
}




const char *byte_to_binary(unsigned char x)
{
    static char b[9];
    b[0] = '\0';

    int z = 128;
    for (; z > 0; z >>= 1)
    {
        strcat(b, ((x & z) == z) ? "1" : "0");
    }
    return b;
}


template< typename T >
void value_to_binary_string( T value, std::string& result )
{
  const int     byte_count_max = sizeof(T);
  unsigned char in_value;
  result.clear();
  for(int icount = byte_count_max - 1 ; icount >= 0 ; icount --)
  {
    in_value = 0xFF & (value >> (8 * icount));
    result = result + std::string(byte_to_binary(in_value)) + ((icount > 0) ? ":" : "");
  }
}


int main()
{

  unsigned int x = 1;
  unsigned int result = 0;

  std::string result_binary;
  std::string in_binary;
  
  for(; x < 10; x++)
  {
    result = snoob(x);
    value_to_binary_string<unsigned int>(x, in_binary);
    value_to_binary_string<unsigned int>(result, result_binary);

    printf("%d[%s] = snoob(%d[%s])\n", result, result_binary.c_str(), x, in_binary.c_str());
  }
  return 0;
}
